﻿Imports System
Imports System.CodeDom
Imports System.Collections.Generic
Imports System.Configuration
Imports System.Diagnostics.CodeAnalysis
Imports System.Globalization
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.Activities.Rules
    Public Class RuleValidation
        ' Methods
        Friend Sub New(ByVal thisObject As Object)
            Me.errors = New ValidationErrorCollection
            Me.typesUsed = New Dictionary([Of] String, Type)(&H10)
            Me.activeParentNodes = New Stack([Of] CodeExpression)
            Me.expressionInfoMap = New Dictionary([Of] CodeExpression, RuleExpressionInfo)
            Me.typeRefMap = New Dictionary([Of] CodeTypeReference, Type)
            If (thisObject Is Nothing) Then
                Throw New ArgumentNullException("thisObject")
            End If
            Me.thisType = thisObject.GetType
            Me.typeProvider = New SimpleRunTimeTypeProvider(Me.thisType.Assembly)
        End Sub

        Public Sub New(ByVal thisType As Type, ByVal typeProvider As ITypeProvider)
            Me.errors = New ValidationErrorCollection
            Me.typesUsed = New Dictionary([Of] String, Type)(&H10)
            Me.activeParentNodes = New Stack([Of] CodeExpression)
            Me.expressionInfoMap = New Dictionary([Of] CodeExpression, RuleExpressionInfo)
            Me.typeRefMap = New Dictionary([Of] CodeTypeReference, Type)
            If (thisType Is Nothing) Then
                Throw New ArgumentNullException("thisType")
            End If
            Me.thisType = thisType
            Me.typeProvider = If((Not typeProvider Is Nothing), typeProvider, New SimpleRunTimeTypeProvider(Me.thisType.Assembly))
        End Sub

        Public Sub New(ByVal activity As Activity, ByVal typeProvider As ITypeProvider, ByVal checkStaticType As Boolean)
            Me.errors = New ValidationErrorCollection
            Me.typesUsed = New Dictionary([Of] String, Type)(&H10)
            Me.activeParentNodes = New Stack([Of] CodeExpression)
            Me.expressionInfoMap = New Dictionary([Of] CodeExpression, RuleExpressionInfo)
            Me.typeRefMap = New Dictionary([Of] CodeTypeReference, Type)
            If (activity Is Nothing) Then
                Throw New ArgumentNullException("activity")
            End If
            If (typeProvider Is Nothing) Then
                Throw New ArgumentNullException("typeProvider")
            End If
            Me.thisType = ConditionHelper.GetContextType(typeProvider, activity)
            Me.typeProvider = typeProvider
            Me.checkStaticType = checkStaticType
            If checkStaticType Then
                Me.authorizedTypes = [TryCast](ConfigurationManager.GetSection("System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes"),List([Of] AuthorizedType))
            End If
        End Sub

        Friend Sub AddError(ByVal [error] As ValidationError)
            Me.Errors.Add([error])
        End Sub

        Private Shared Sub AddExplicitConversions(ByVal t As Type, ByVal source As Type, ByVal target As Type, ByVal methods As List([Of] MethodInfo))
            Dim info As MethodInfo
            For Each info In t.GetMethods((BindingFlags.Public Or BindingFlags.Static))
                If (((info.Name = "op_Implicit") OrElse (info.Name = "op_Explicit")) AndAlso (info.GetParameters.Length = 1)) Then
                    Dim error As ValidationError
                    Dim parameterType As Type = info.GetParameters(0).ParameterType
                    Dim returnType As Type = info.ReturnType
                    If (((RuleValidation.StandardImplicitConversion(source, parameterType, Nothing, [error]) OrElse RuleValidation.StandardImplicitConversion(parameterType, source, Nothing, [error])) AndAlso (RuleValidation.StandardImplicitConversion(target, returnType, Nothing, [error]) OrElse RuleValidation.StandardImplicitConversion(returnType, target, Nothing, [error]))) AndAlso Not methods.Contains(info)) Then
                        methods.Add(info)
                    End If
                End If
            Next
        End Sub

        Private Shared Sub AddImplicitConversions(ByVal t As Type, ByVal source As Type, ByVal target As Type, ByVal methods As List([Of] MethodInfo))
            Dim info As MethodInfo
            For Each info In t.GetMethods((BindingFlags.Public Or BindingFlags.Static))
                If ((info.Name = "op_Implicit") AndAlso (info.GetParameters.Length = 1)) Then
                    Dim error As ValidationError
                    Dim parameterType As Type = info.GetParameters(0).ParameterType
                    Dim returnType As Type = info.ReturnType
                    If ((RuleValidation.StandardImplicitConversion(source, parameterType, Nothing, [error]) AndAlso RuleValidation.StandardImplicitConversion(returnType, target, Nothing, [error])) AndAlso Not methods.Contains(info)) Then
                        methods.Add(info)
                    End If
                End If
            Next
        End Sub

        Friend Sub AddTypeReference(ByVal typeRef As CodeTypeReference, ByVal type As Type)
            Me.typeRefMap.Item(typeRef) = type
        End Sub

        Friend Function AllowInternalMembers(ByVal type As Type) As Boolean
            Return (type.Assembly Is Me.thisType.Assembly)
        End Function

        <SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")> _
        Private Shared Function CheckValueRange(ByVal rhsExpression As CodeExpression, ByVal lhsType As Type, <Out> ByRef [error] As ValidationError) As Boolean
            [error] = Nothing
            Dim expression As CodePrimitiveExpression = [TryCast](rhsExpression,CodePrimitiveExpression)
            If (Not expression Is Nothing) Then
                Try 
                    Convert.ChangeType(expression.Value, lhsType, CultureInfo.CurrentCulture)
                    Return True
                Catch exception As Exception
                    [error] = New ValidationError(exception.Message, &H545)
                    Return False
                End Try
            End If
            Return False
        End Function

        Private Sub DetermineExtensionMethods()
            Me.extensionMethods = New List([Of] ExtensionMethodInfo)
            Me.SetExtensionAttribute
            If (Not Me.extensionAttribute Is Nothing) Then
                Me.seenAssemblies = New List([Of] Assembly)
                Dim localAssembly As Assembly = Me.typeProvider.LocalAssembly
                If (Not localAssembly Is Nothing) Then
                    Me.DetermineExtensionMethods(localAssembly)
                    Dim assembly2 As Assembly
                    For Each assembly2 In Me.typeProvider.ReferencedAssemblies
                        Me.DetermineExtensionMethods(assembly2)
                    Next
                Else
                    Me.DetermineExtensionMethods(Me.typeProvider.GetTypes)
                End If
            End If
        End Sub

        Private Sub DetermineExtensionMethods(ByVal types As Type())
            Dim type As Type
            For Each type In types
                If (((Not type Is Nothing) AndAlso (type.IsPublic OrElse type.IsNestedPublic)) AndAlso (type.IsSealed AndAlso Me.IsMarkedExtension(type))) Then
                    Dim info As MethodInfo
                    For Each info In type.GetMethods((BindingFlags.Public Or BindingFlags.Static))
                        If ((info.IsStatic AndAlso Not info.IsGenericMethod) AndAlso Me.IsMarkedExtension(info)) Then
                            Dim parameters As ParameterInfo() = info.GetParameters
                            If (parameters.Length > 0) Then
                                Me.extensionMethods.Add(New ExtensionMethodInfo(info, parameters))
                            End If
                        End If
                    Next
                End If
            Next
        End Sub

        Friend Sub DetermineExtensionMethods(ByVal [assembly] As Assembly)
            If (((Not Me.extensionAttribute Is Nothing) AndAlso (Not [assembly] Is Nothing)) AndAlso Not Me.seenAssemblies.Contains([assembly])) Then
                Me.seenAssemblies.Add([assembly])
                If Me.IsMarkedExtension([assembly]) Then
                    Dim types As Type()
                    Try 
                        types = [assembly].GetTypes
                    Catch exception As ReflectionTypeLoadException
                        types = exception.Types
                    End Try
                    Me.DetermineExtensionMethods(types)
                End If
            End If
        End Sub

        Private Shared Sub EvaluateCandidate(ByVal candidates As List([Of] CandidateMember), ByVal candidateMember As MemberInfo, ByVal parameters As ParameterInfo(), ByVal arguments As List([Of] Argument), <Out> ByRef [error] As ValidationError, ByVal buildArgCountMismatchError As BuildArgCountMismatchError)
            [error] = Nothing
            Dim count As Integer = arguments.Count
            Dim name As String = candidateMember.Name
            If ((parameters Is Nothing) OrElse (parameters.Length = 0)) Then
                If (count = 0) Then
                    candidates.Add(New CandidateMember(candidateMember))
                Else
                    [error] = buildArgCountMismatchError.Invoke(name, count)
                End If
            Else
                Dim signature As New List([Of] CandidateParameter)
                Dim length As Integer = parameters.Length
                Dim num3 As Integer = length
                Dim paramInfo As ParameterInfo = parameters((length - 1))
                If paramInfo.ParameterType.IsArray Then
                    Dim customAttributes As Object() = paramInfo.GetCustomAttributes(GetType(ParamArrayAttribute), False)
                    If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length > 0)) Then
                        num3 -= 1
                    End If
                End If
                If (count < num3) Then
                    [error] = buildArgCountMismatchError.Invoke(name, count)
                ElseIf ((num3 = length) AndAlso (count <> length)) Then
                    [error] = buildArgCountMismatchError.Invoke(name, count)
                Else
                    Dim index As Integer = 0
                    Do While (index < num3)
                        Dim item As New CandidateParameter(parameters(index))
                        If Not item.Match(arguments.Item(index), name, (index + 1), [error]) Then
                            Exit Do
                        End If
                        signature.Add(item)
                        index += 1
                    Loop
                    If (index = num3) Then
                        If (num3 < length) Then
                            Dim member As CandidateMember = Nothing
                            If (count = num3) Then
                                member = New CandidateMember(candidateMember, parameters, signature, Form.Expanded)
                            ElseIf (count = length) Then
                                Dim parameter2 As New CandidateParameter(paramInfo)
                                If parameter2.Match(arguments.Item(index), name, (index + 1), [error]) Then
                                    signature.Add(parameter2)
                                    member = New CandidateMember(candidateMember, parameters, signature, Form.Normal)
                                End If
                            End If
                            If (member Is Nothing) Then
                                Dim parameter3 As New CandidateParameter(paramInfo.ParameterType.GetElementType)
                                Do While (index < count)
                                    If Not parameter3.Match(arguments.Item(index), name, (index + 1), [error]) Then
                                        Return
                                    End If
                                    signature.Add(parameter3)
                                    index += 1
                                Loop
                                member = New CandidateMember(candidateMember, parameters, signature, Form.Expanded)
                            End If
                            candidates.Add(member)
                        Else
                            candidates.Add(New CandidateMember(candidateMember, parameters, signature, Form.Normal))
                        End If
                    End If
                End If
            End If
        End Sub

        Friend Shared Function ExplicitConversionSpecified(ByVal fromType As Type, ByVal toType As Type, <Out> ByRef [error] As ValidationError) As Boolean
            If Not RuleValidation.StandardImplicitConversion(fromType, toType, Nothing, [error]) Then
                Dim error2 As ValidationError
                If (Not [error] Is Nothing) Then
                    Return False
                End If
                If ((fromType.IsValueType AndAlso toType.IsValueType) AndAlso RuleValidation.IsExplicitNumericConversion(fromType, toType)) Then
                    Return True
                End If
                If RuleValidation.StandardImplicitConversion(toType, fromType, Nothing, error2) Then
                    Return True
                End If
                If toType.IsInterface Then
                    If (fromType.IsClass AndAlso Not fromType.IsSealed) Then
                        Return True
                    End If
                    If fromType.IsInterface Then
                        Return True
                    End If
                End If
                If ((fromType.IsInterface AndAlso toType.IsClass) AndAlso (Not toType.IsSealed OrElse RuleValidation.InterfaceMatch(toType.GetInterfaces, fromType))) Then
                    Return True
                End If
                If (RuleValidation.FindExplicitConversion(fromType, toType, [error]) Is Nothing) Then
                    Return False
                End If
            End If
            Return True
        End Function

        Public Function ExpressionInfo(ByVal expression As CodeExpression) As RuleExpressionInfo
            If (expression Is Nothing) Then
                Throw New ArgumentNullException("expression")
            End If
            Dim info As RuleExpressionInfo = Nothing
            Me.expressionInfoMap.TryGetValue(expression, info)
            Return info
        End Function

        Friend Function FindBestCandidate(ByVal targetType As Type, ByVal methods As List([Of] MethodInfo), ByVal ParamArray types As Type()) As MethodInfo
            Dim arguments As New List([Of] Argument)
            Dim type As Type
            For Each type In types
                arguments.Add(New Argument(type))
            Next
            Dim candidates As New List([Of] CandidateMember)(methods.Count)
            Dim info As MethodInfo
            For Each info In methods
                Dim error As ValidationError = Nothing
                RuleValidation.EvaluateCandidate(candidates, info, info.GetParameters, arguments, [error], Function (ByVal name As String, ByVal numArguments As Integer) 
                    Return New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.MethodArgCountMismatch, New Object() { name, numArguments }), &H196)
                End Function)
            Next
            If (candidates.Count = 0) Then
                Return Nothing
            End If
            Dim member As CandidateMember = Me.FindBestCandidate(targetType, candidates, arguments)
            If (member Is Nothing) Then
                Return Nothing
            End If
            Return DirectCast(member.Member, MethodInfo)
        End Function

        Private Function FindBestCandidate(ByVal targetType As Type, ByVal candidates As List([Of] CandidateMember), ByVal arguments As List([Of] Argument)) As CandidateMember
            Dim count As Integer = candidates.Count
            Dim list As New List([Of] CandidateMember)(1) { candidates.Item(0) }
            Dim i As Integer
            For i = 1 To count - 1
                Dim item As CandidateMember = candidates.Item(i)
                Dim other As CandidateMember = list.Item(0)
                Dim num3 As Integer = item.CompareMember(targetType, other, arguments, Me)
                If (num3 > 0) Then
                    list.Clear
                    list.Add(item)
                ElseIf (num3 = 0) Then
                    list.Add(item)
                End If
            Next i
            If (list.Count = 1) Then
                Return list.Item(0)
            End If
            Return Nothing
        End Function

        <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
        Friend Shared Function FindExplicitConversion(ByVal fromType As Type, ByVal toType As Type, <Out> ByRef [error] As ValidationError) As MethodInfo
            Dim error2 As ValidationError
            Dim methods As New List([Of] MethodInfo)
            Dim flag As Boolean = ConditionHelper.IsNullableValueType(fromType)
            Dim flag2 As Boolean = ConditionHelper.IsNullableValueType(toType)
            Dim t As Type = If(flag, Nullable.GetUnderlyingType(fromType), fromType)
            Dim type2 As Type = If(flag2, Nullable.GetUnderlyingType(toType), toType)
            If t.IsClass Then
                RuleValidation.AddExplicitConversions(t, fromType, toType, methods)
                Dim type3 As Type = t.BaseType
                Do While ((Not type3 Is Nothing) AndAlso (Not type3 Is GetType(Object)))
                    RuleValidation.AddExplicitConversions(type3, fromType, toType, methods)
                    type3 = type3.BaseType
                Loop
            ElseIf RuleValidation.IsStruct(t) Then
                RuleValidation.AddExplicitConversions(t, fromType, toType, methods)
            End If
            If type2.IsClass Then
                RuleValidation.AddExplicitConversions(type2, fromType, toType, methods)
                Dim type4 As Type = type2.BaseType
                Do While ((Not type4 Is Nothing) AndAlso (Not type4 Is GetType(Object)))
                    RuleValidation.AddExplicitConversions(type4, fromType, toType, methods)
                    type4 = type4.BaseType
                Loop
            ElseIf RuleValidation.IsStruct(type2) Then
                RuleValidation.AddExplicitConversions(type2, fromType, toType, methods)
            End If
            If (flag AndAlso flag2) Then
                Dim list2 As New List([Of] MethodInfo)
                If t.IsClass Then
                    RuleValidation.AddExplicitConversions(t, t, type2, list2)
                    Dim type5 As Type = t.BaseType
                    Do While ((Not type5 Is Nothing) AndAlso (Not type5 Is GetType(Object)))
                        RuleValidation.AddExplicitConversions(type5, t, type2, list2)
                        type5 = type5.BaseType
                    Loop
                ElseIf RuleValidation.IsStruct(t) Then
                    RuleValidation.AddExplicitConversions(t, t, type2, list2)
                End If
                If type2.IsClass Then
                    RuleValidation.AddExplicitConversions(type2, t, type2, list2)
                    Dim type6 As Type = type2.BaseType
                    Do While ((Not type6 Is Nothing) AndAlso (Not type6 Is GetType(Object)))
                        RuleValidation.AddExplicitConversions(type6, t, type2, list2)
                        type6 = type6.BaseType
                    Loop
                ElseIf RuleValidation.IsStruct(type2) Then
                    RuleValidation.AddExplicitConversions(type2, t, type2, list2)
                End If
                Dim info As MethodInfo
                For Each info In list2
                    methods.Add(New LiftedConversionMethodInfo(info))
                Next
            End If
            If (methods.Count = 0) Then
                Dim str As String = String.Format(CultureInfo.CurrentCulture, Messages.NoConversion, New Object() { RuleDecompiler.DecompileType(fromType), RuleDecompiler.DecompileType(toType) })
                [error] = New ValidationError(str, &H545)
                Return Nothing
            End If
            Dim lhsType As Type = Nothing
            Dim i As Integer
            For i = 0 To methods.Count - 1
                If (methods.Item(i).GetParameters(0).ParameterType Is fromType) Then
                    lhsType = fromType
                    Exit For
                End If
            Next i
            If (lhsType Is Nothing) Then
                Dim m As Integer
                For m = 0 To methods.Count - 1
                    Dim parameterType As Type = methods.Item(m).GetParameters(0).ParameterType
                    If RuleValidation.StandardImplicitConversion(fromType, parameterType, Nothing, error2) Then
                        If (lhsType Is Nothing) Then
                            lhsType = parameterType
                        ElseIf RuleValidation.StandardImplicitConversion(parameterType, lhsType, Nothing, error2) Then
                            lhsType = parameterType
                        End If
                    End If
                Next m
            End If
            If (lhsType Is Nothing) Then
                Dim n As Integer
                For n = 0 To methods.Count - 1
                    Dim type10 As Type = methods.Item(n).GetParameters(0).ParameterType
                    If RuleValidation.StandardImplicitConversion(type10, fromType, Nothing, error2) Then
                        If (lhsType Is Nothing) Then
                            lhsType = type10
                        ElseIf RuleValidation.StandardImplicitConversion(lhsType, type10, Nothing, error2) Then
                            lhsType = type10
                        End If
                    End If
                Next n
            End If
            Dim rhsType As Type = Nothing
            Dim j As Integer
            For j = 0 To methods.Count - 1
                If (methods.Item(j).ReturnType Is toType) Then
                    rhsType = toType
                    Exit For
                End If
            Next j
            If (rhsType Is Nothing) Then
                Dim num5 As Integer
                For num5 = 0 To methods.Count - 1
                    Dim returnType As Type = methods.Item(num5).ReturnType
                    If RuleValidation.StandardImplicitConversion(returnType, toType, Nothing, error2) Then
                        If (rhsType Is Nothing) Then
                            rhsType = returnType
                        ElseIf RuleValidation.StandardImplicitConversion(rhsType, returnType, Nothing, error2) Then
                            rhsType = returnType
                        End If
                    End If
                Next num5
            End If
            If (rhsType Is Nothing) Then
                Dim num6 As Integer
                For num6 = 0 To methods.Count - 1
                    Dim type14 As Type = methods.Item(num6).ReturnType
                    If RuleValidation.StandardImplicitConversion(toType, type14, Nothing, error2) Then
                        If (rhsType Is Nothing) Then
                            rhsType = type14
                        ElseIf RuleValidation.StandardImplicitConversion(type14, rhsType, Nothing, error2) Then
                            rhsType = type14
                        End If
                    End If
                Next num6
            End If
            Dim num7 As Integer = 0
            Dim num8 As Integer = 0
            Dim k As Integer
            For k = 0 To methods.Count - 1
                If (((methods.Item(k).ReturnType Is rhsType) AndAlso (methods.Item(k).GetParameters(0).ParameterType Is lhsType)) AndAlso Not TypeOf methods.Item(k) Is LiftedConversionMethodInfo) Then
                    num8 = k
                    num7 += 1
                End If
            Next k
            If (num7 = 1) Then
                [error] = Nothing
                Return methods.Item(num8)
            End If
            If (flag2 AndAlso (num7 = 0)) Then
                If flag Then
                    Dim num10 As Integer
                    For num10 = 0 To methods.Count - 1
                        If (((methods.Item(num10).ReturnType Is rhsType) AndAlso (methods.Item(num10).GetParameters(0).ParameterType Is lhsType)) AndAlso TypeOf methods.Item(num10) Is LiftedConversionMethodInfo) Then
                            num8 = num10
                            num7 += 1
                        End If
                    Next num10
                    If (num7 = 1) Then
                        [error] = Nothing
                        Return methods.Item(num8)
                    End If
                Else
                    Dim method As MethodInfo = RuleValidation.FindExplicitConversion(fromType, type2, [error])
                    If (Not method Is Nothing) Then
                        [error] = Nothing
                        Return New LiftedConversionMethodInfo(method)
                    End If
                End If
            End If
            Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.AmbiguousConversion, New Object() { RuleDecompiler.DecompileType(fromType), RuleDecompiler.DecompileType(toType) })
            [error] = New ValidationError(errorText, &H545)
            Return Nothing
        End Function

        <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
        Friend Shared Function FindImplicitConversion(ByVal fromType As Type, ByVal toType As Type, <Out> ByRef [error] As ValidationError) As MethodInfo
            Dim error2 As ValidationError
            Dim methods As New List([Of] MethodInfo)
            Dim flag As Boolean = ConditionHelper.IsNullableValueType(fromType)
            Dim flag2 As Boolean = ConditionHelper.IsNullableValueType(toType)
            Dim t As Type = If(flag, Nullable.GetUnderlyingType(fromType), fromType)
            Dim type As Type = If(flag2, Nullable.GetUnderlyingType(toType), toType)
            If t.IsClass Then
                RuleValidation.AddImplicitConversions(t, fromType, toType, methods)
                Dim type3 As Type = t.BaseType
                Do While ((Not type3 Is Nothing) AndAlso (Not type3 Is GetType(Object)))
                    RuleValidation.AddImplicitConversions(type3, fromType, toType, methods)
                    type3 = type3.BaseType
                Loop
            ElseIf RuleValidation.IsStruct(t) Then
                RuleValidation.AddImplicitConversions(t, fromType, toType, methods)
            End If
            If (type.IsClass OrElse RuleValidation.IsStruct(type)) Then
                RuleValidation.AddImplicitConversions(type, fromType, toType, methods)
            End If
            If (flag AndAlso flag2) Then
                Dim list2 As New List([Of] MethodInfo)
                If t.IsClass Then
                    RuleValidation.AddImplicitConversions(t, t, type, list2)
                    Dim type4 As Type = t.BaseType
                    Do While ((Not type4 Is Nothing) AndAlso (Not type4 Is GetType(Object)))
                        RuleValidation.AddImplicitConversions(type4, t, type, list2)
                        type4 = type4.BaseType
                    Loop
                ElseIf RuleValidation.IsStruct(t) Then
                    RuleValidation.AddImplicitConversions(t, t, type, list2)
                End If
                If (type.IsClass OrElse RuleValidation.IsStruct(type)) Then
                    RuleValidation.AddImplicitConversions(type, t, type, list2)
                End If
                Dim info As MethodInfo
                For Each info In list2
                    Dim parameters As ParameterInfo() = info.GetParameters
                    If (ConditionHelper.IsNonNullableValueType(info.ReturnType) AndAlso ConditionHelper.IsNonNullableValueType(parameters(0).ParameterType)) Then
                        methods.Add(New LiftedConversionMethodInfo(info))
                    End If
                Next
            End If
            If (methods.Count = 0) Then
                Dim str As String = String.Format(CultureInfo.CurrentCulture, Messages.NoConversion, New Object() { RuleDecompiler.DecompileType(fromType), RuleDecompiler.DecompileType(toType) })
                [error] = New ValidationError(str, &H545)
                Return Nothing
            End If
            Dim parameterType As Type = methods.Item(0).GetParameters(0).ParameterType
            If (Not parameterType Is fromType) Then
                Dim j As Integer
                For j = 1 To methods.Count - 1
                    Dim rhsType As Type = methods.Item(j).GetParameters(0).ParameterType
                    If (rhsType Is fromType) Then
                        parameterType = fromType
                        Exit For
                    End If
                    If RuleValidation.StandardImplicitConversion(rhsType, parameterType, Nothing, error2) Then
                        parameterType = rhsType
                    End If
                Next j
            End If
            Dim returnType As Type = methods.Item(0).ReturnType
            If (Not returnType Is toType) Then
                Dim k As Integer
                For k = 1 To methods.Count - 1
                    Dim lhsType As Type = methods.Item(k).ReturnType
                    If (lhsType Is toType) Then
                        returnType = toType
                        Exit For
                    End If
                    If RuleValidation.StandardImplicitConversion(returnType, lhsType, Nothing, error2) Then
                        returnType = lhsType
                    End If
                Next k
            End If
            Dim num3 As Integer = 0
            Dim num4 As Integer = 0
            Dim i As Integer
            For i = 0 To methods.Count - 1
                If (((methods.Item(i).ReturnType Is returnType) AndAlso (methods.Item(i).GetParameters(0).ParameterType Is parameterType)) AndAlso Not TypeOf methods.Item(i) Is LiftedConversionMethodInfo) Then
                    num4 = i
                    num3 += 1
                End If
            Next i
            If (num3 = 1) Then
                [error] = Nothing
                Return methods.Item(num4)
            End If
            If (flag2 AndAlso (num3 = 0)) Then
                If flag Then
                    Dim m As Integer
                    For m = 0 To methods.Count - 1
                        If (((methods.Item(m).ReturnType Is returnType) AndAlso (methods.Item(m).GetParameters(0).ParameterType Is parameterType)) AndAlso TypeOf methods.Item(m) Is LiftedConversionMethodInfo) Then
                            num4 = m
                            num3 += 1
                        End If
                    Next m
                    If (num3 = 1) Then
                        [error] = Nothing
                        Return methods.Item(num4)
                    End If
                Else
                    Dim method As MethodInfo = RuleValidation.FindImplicitConversion(fromType, type, [error])
                    If (Not method Is Nothing) Then
                        [error] = Nothing
                        Return New LiftedConversionMethodInfo(method)
                    End If
                End If
            End If
            Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.AmbiguousConversion, New Object() { RuleDecompiler.DecompileType(fromType), RuleDecompiler.DecompileType(toType) })
            [error] = New ValidationError(errorText, &H545)
            Return Nothing
        End Function

        Private Function FindType(ByVal typeName As String) As Type
            If (typeName Is Nothing) Then
                Throw New ArgumentNullException("typeName")
            End If
            Dim type As Type = Nothing
            If Not Me.typesUsed.TryGetValue(typeName, type) Then
                type = Me.typeProvider.GetType(typeName, False)
                If (type Is Nothing) Then
                    Return type
                End If
                Me.typesUsed.Add(typeName, type)
                If Not Me.checkStaticType Then
                    Return type
                End If
                If (Me.authorizedTypes Is Nothing) Then
                    Dim item As New ValidationError(Messages.Error_ConfigFileMissingOrInvalid, &H178)
                    Me.Errors.Add(item)
                    Return type
                End If
                Dim assemblyQualifiedName As String = type.AssemblyQualifiedName
                Dim flag As Boolean = False
                Dim type2 As AuthorizedType
                For Each type2 In Me.authorizedTypes
                    If type2.RegularExpression.IsMatch(assemblyQualifiedName) Then
                        flag = (String.Compare(Boolean.TrueString, type2.Authorized, StringComparison.OrdinalIgnoreCase) = 0)
                        If Not flag Then
                            Exit For
                        End If
                    End If
                Next
                If Not flag Then
                    Dim error2 As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.Error_TypeNotAuthorized, New Object() { type.FullName }), &H16B)
                    error2.UserData.Item("ErrorObject") = type
                    Me.Errors.Add(error2)
                End If
            End If
            Return type
        End Function

        Private Shared Function GetCandidateConstructors(ByVal constructors As List([Of] ConstructorInfo), ByVal arguments As List([Of] Argument), <Out> ByRef [error] As ValidationError) As List([Of] CandidateMember)
            Dim candidates As New List([Of] CandidateMember)
            [error] = Nothing
            Dim num As Integer = 0
            Dim info As ConstructorInfo
            For Each info In constructors
                Dim error2 As ValidationError = Nothing
                RuleValidation.EvaluateCandidate(candidates, info, info.GetParameters, arguments, error2, Function (ByVal name As String, ByVal numArguments As Integer) 
                    Return New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.MethodArgCountMismatch, New Object() { name, numArguments }), &H196)
                End Function)
                [error] = error2
                If (Not error2 Is Nothing) Then
                    num += 1
                End If
            Next
            If (candidates.Count = 0) Then
                If (num > 1) Then
                    Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.ConstructorOverloadNotFound, New Object(0  - 1) {})
                    [error] = New ValidationError(errorText, &H199)
                End If
                Return Nothing
            End If
            [error] = Nothing
            Return candidates
        End Function

        Private Shared Function GetCandidateIndexers(ByVal indexerProperties As List([Of] PropertyInfo), ByVal arguments As List([Of] Argument), <Out> ByRef [error] As ValidationError) As List([Of] CandidateMember)
            Dim candidates As New List([Of] CandidateMember)
            [error] = Nothing
            Dim num As Integer = 0
            Dim info As PropertyInfo
            For Each info In indexerProperties
                Dim error2 As ValidationError = Nothing
                RuleValidation.EvaluateCandidate(candidates, info, info.GetIndexParameters, arguments, error2, Function (ByVal propName As String, ByVal numArguments As Integer) 
                    Return New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.IndexerCountMismatch, New Object() { numArguments }), &H19F)
                End Function)
                [error] = error2
                If (Not error2 Is Nothing) Then
                    num += 1
                End If
            Next
            If (candidates.Count = 0) Then
                If (num > 1) Then
                    Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.IndexerOverloadNotFound, New Object(0  - 1) {})
                    [error] = New ValidationError(errorText, &H1A1)
                End If
                Return Nothing
            End If
            [error] = Nothing
            Return candidates
        End Function

        Private Shared Function GetCandidateMethods(ByVal methodName As String, ByVal methods As List([Of] MethodInfo), ByVal arguments As List([Of] Argument), <Out> ByRef [error] As ValidationError) As List([Of] CandidateMember)
            Dim candidates As New List([Of] CandidateMember)
            [error] = Nothing
            Dim num As Integer = 0
            Dim info As MethodInfo
            For Each info In methods
                Dim error2 As ValidationError = Nothing
                RuleValidation.EvaluateCandidate(candidates, info, info.GetParameters, arguments, error2, Function (ByVal name As String, ByVal numArguments As Integer) 
                    Return New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.MethodArgCountMismatch, New Object() { name, numArguments }), &H196)
                End Function)
                [error] = error2
                If (Not error2 Is Nothing) Then
                    num += 1
                End If
            Next
            If (candidates.Count = 0) Then
                If (num > 1) Then
                    Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.MethodOverloadNotFound, New Object() { methodName })
                    [error] = New ValidationError(errorText, &H199)
                End If
                Return Nothing
            End If
            [error] = Nothing
            Return candidates
        End Function

        Private Shared Function GetCandidateTargetTypes(ByVal targetType As Type) As List([Of] Type)
            If targetType.IsInterface Then
                Dim list As New List([Of] Type) { targetType }
                Dim i As Integer
                For i = 0 To list.Count - 1
                    list.AddRange(list.Item(i).GetInterfaces)
                Next i
                list.Add(GetType(Object))
                Return list
            End If
            Return New List([Of] Type)(1) { targetType }
        End Function

        Friend Shared Function GetConstructors(ByVal targetTypes As List([Of] Type), ByVal constructorBindingFlags As BindingFlags) As List([Of] ConstructorInfo)
            Dim list As New List([Of] ConstructorInfo)
            Dim i As Integer
            For i = 0 To targetTypes.Count - 1
                Dim type As Type = targetTypes.Item(i)
                Dim info As ConstructorInfo
                For Each info In type.GetConstructors(constructorBindingFlags)
                    If ((Not info.IsGenericMethod AndAlso Not info.IsStatic) AndAlso (Not info.IsPrivate AndAlso Not info.IsFamily)) Then
                        list.Add(info)
                    End If
                Next
            Next i
            Return list
        End Function

        Private Shared Function GetDefaultExtensionAttribute() As Type
            Return Type.GetType("System.Runtime.CompilerServices.ExtensionAttribute, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", False)
        End Function

        Private Shared Function GetIndexerProperties(ByVal candidateTypes As List([Of] Type), ByVal bindingFlags As BindingFlags) As List([Of] PropertyInfo)
            Dim list As New List([Of] PropertyInfo)
            Dim type As Type
            For Each type In candidateTypes
                Dim customAttributes As Object() = type.GetCustomAttributes(GetType(DefaultMemberAttribute), True)
                If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length <> 0)) Then
                    Dim attributeArray As DefaultMemberAttribute() = DirectCast(customAttributes, DefaultMemberAttribute())
                    Dim info As PropertyInfo
                    For Each info In type.GetProperties(bindingFlags)
                        Dim flag As Boolean = False
                        Dim i As Integer
                        For i = 0 To attributeArray.Length - 1
                            If (attributeArray(i).MemberName = info.Name) Then
                                flag = True
                                Exit For
                            End If
                        Next i
                        If (flag AndAlso (info.GetIndexParameters.Length > 0)) Then
                            list.Add(info)
                        End If
                    Next
                End If
            Next
            Return list
        End Function

        Private Function GetNamedMethods(ByVal targetTypes As List([Of] Type), ByVal methodName As String, ByVal methodBindingFlags As BindingFlags) As List([Of] MethodInfo)
            Dim list As New List([Of] MethodInfo)
            Dim extensionMethods As List([Of] ExtensionMethodInfo) = Me.ExtensionMethods
            Dim i As Integer
            For i = 0 To targetTypes.Count - 1
                Dim rhsType As Type = targetTypes.Item(i)
                Dim info As MethodInfo
                For Each info In rhsType.GetMember(methodName, MemberTypes.Method, methodBindingFlags)
                    If Not info.IsGenericMethod Then
                        list.Add(info)
                    End If
                Next
                Dim info2 As ExtensionMethodInfo
                For Each info2 In extensionMethods
                    Dim error As ValidationError
                    If ((info2.Name = methodName) AndAlso RuleValidation.TypesAreAssignable(rhsType, info2.AssumedDeclaringType, Nothing, [error])) Then
                        list.Add(info2)
                    End If
                Next
            Next i
            Return list
        End Function

        Private Shared Function GetProperty(ByVal targetType As Type, ByVal propertyName As String, ByVal bindingFlags As BindingFlags) As PropertyInfo
            Dim info As PropertyInfo
            For Each info In targetType.GetMember(propertyName, MemberTypes.Property, bindingFlags)
                Dim indexParameters As ParameterInfo() = info.GetIndexParameters
                If ((indexParameters Is Nothing) OrElse (indexParameters.Length = 0)) Then
                    Return info
                End If
            Next
            Return Nothing
        End Function

        Friend Function GetTypeProvider() As ITypeProvider
            Return Me.typeProvider
        End Function

        Friend Shared Function ImplicitConversion(ByVal fromType As Type, ByVal toType As Type) As Boolean
            Dim error As ValidationError
            Return (RuleValidation.StandardImplicitConversion(fromType, toType, Nothing, [error]) OrElse (Not RuleValidation.FindImplicitConversion(fromType, toType, [error]) Is Nothing))
        End Function

        Private Shared Function InterfaceMatch(ByVal types As Type(), ByVal fromType As Type) As Boolean
            Dim type As Type
            For Each type In types
                If (type Is fromType) Then
                    Return True
                End If
            Next
            Return False
        End Function

        <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
        Private Shared Function IsExplicitNumericConversion(ByVal sourceType As Type, ByVal testType As Type) As Boolean
            Dim code As TypeCode = If(ConditionHelper.IsNullableValueType(sourceType), Type.GetTypeCode(sourceType.GetGenericArguments(0)), Type.GetTypeCode(sourceType))
            Dim code2 As TypeCode = If(ConditionHelper.IsNullableValueType(testType), Type.GetTypeCode(testType.GetGenericArguments(0)), Type.GetTypeCode(testType))
            Select Case code
                Case TypeCode.Char
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.[SByte]
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Byte
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Int16
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.UInt16
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Int32
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.UInt32
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Int64
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.UInt64
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Single
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Double
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
                Case TypeCode.Decimal
                    Select Case code2
                        Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double, TypeCode.Decimal
                            Return True
                    End Select
                    Return False
            End Select
            Return False
        End Function

        Friend Shared Function IsInternal(ByVal fieldInfo As FieldInfo) As Boolean
            If Not fieldInfo.IsAssembly Then
                Return fieldInfo.IsFamilyAndAssembly
            End If
            Return True
        End Function

        Friend Shared Function IsInternal(ByVal methodInfo As MethodInfo) As Boolean
            If Not methodInfo.IsAssembly Then
                Return methodInfo.IsFamilyAndAssembly
            End If
            Return True
        End Function

        Private Function IsMarkedExtension(ByVal [assembly] As Assembly) As Boolean
            If (Not Me.extensionAttribute Is Nothing) Then
                Dim customAttributes As Object() = [assembly].GetCustomAttributes(Me.extensionAttribute, False)
                If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length > 0)) Then
                    Return True
                End If
            End If
            Return False
        End Function

        Private Function IsMarkedExtension(ByVal mi As MethodInfo) As Boolean
            If (Not Me.extensionAttribute Is Nothing) Then
                Dim customAttributes As Object() = mi.GetCustomAttributes(Me.extensionAttribute, False)
                If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length > 0)) Then
                    Return True
                End If
            End If
            Return False
        End Function

        Private Function IsMarkedExtension(ByVal type As Type) As Boolean
            If (Not Me.extensionAttribute Is Nothing) Then
                Dim customAttributes As Object() = type.GetCustomAttributes(Me.extensionAttribute, False)
                If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length > 0)) Then
                    Return True
                End If
            End If
            Return False
        End Function

        Friend Shared Function IsPrivate(ByVal fieldInfo As FieldInfo) As Boolean
            If ((Not fieldInfo.IsPrivate AndAlso Not fieldInfo.IsFamily) AndAlso Not fieldInfo.IsFamilyOrAssembly) Then
                Return fieldInfo.IsFamilyAndAssembly
            End If
            Return True
        End Function

        Friend Shared Function IsPrivate(ByVal methodInfo As MethodInfo) As Boolean
            If ((Not methodInfo.IsPrivate AndAlso Not methodInfo.IsFamily) AndAlso Not methodInfo.IsFamilyOrAssembly) Then
                Return methodInfo.IsFamilyAndAssembly
            End If
            Return True
        End Function

        Private Shared Function IsStruct(ByVal type As Type) As Boolean
            Return (type.IsValueType AndAlso Not type.IsPrimitive)
        End Function

        Friend Shared Function IsValidBooleanResult(ByVal type As Type) As Boolean
            If ((Not type Is GetType(Boolean)) AndAlso (Not type Is GetType(Nullable([Of] Boolean)))) Then
                Return RuleValidation.ImplicitConversion(type, GetType(Boolean))
            End If
            Return True
        End Function

        Public Sub PopParentExpression()
            Me.activeParentNodes.Pop
        End Sub

        Public Function PushParentExpression(ByVal newParent As CodeExpression) As Boolean
            If (newParent Is Nothing) Then
                Throw New ArgumentNullException("newParent")
            End If
            If Me.activeParentNodes.Contains(newParent) Then
                Dim item As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.CyclicalExpression, New Object(0  - 1) {}), &H179)
                item.UserData.Item("ErrorObject") = newParent
                Me.Errors.Add(item)
                Return False
            End If
            Me.activeParentNodes.Push(newParent)
            Return True
        End Function

        Friend Function ResolveConstructor(ByVal targetType As Type, ByVal constructorBindingFlags As BindingFlags, ByVal argumentExprs As List([Of] CodeExpression), <Out> ByRef [error] As ValidationError) As RuleConstructorExpressionInfo
            Dim str As String
            Dim arguments As New List([Of] Argument)(argumentExprs.Count)
            Dim expression As CodeExpression
            For Each expression In argumentExprs
                arguments.Add(New Argument(expression, Me))
            Next
            Dim constructors As List([Of] ConstructorInfo) = RuleValidation.GetConstructors(RuleValidation.GetCandidateTargetTypes(targetType), constructorBindingFlags)
            If (constructors.Count = 0) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.UnknownConstructor, New Object() { RuleDecompiler.DecompileType(targetType) })
                [error] = New ValidationError(str, &H137)
                Return Nothing
            End If
            Dim candidates As List([Of] CandidateMember) = RuleValidation.GetCandidateConstructors(constructors, arguments, [error])
            If (candidates Is Nothing) Then
                Return Nothing
            End If
            Dim member As CandidateMember = Me.FindBestCandidate(targetType, candidates, arguments)
            If (member Is Nothing) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.AmbiguousConstructor, New Object() { RuleDecompiler.DecompileType(targetType) })
                [error] = New ValidationError(str, &H54A)
                Return Nothing
            End If
            Return New RuleConstructorExpressionInfo(DirectCast(member.Member, ConstructorInfo), member.IsExpanded)
        End Function

        Friend Function ResolveFieldOrProperty(ByVal targetType As Type, ByVal name As String) As MemberInfo
            Dim bindingAttr As BindingFlags = (BindingFlags.FlattenHierarchy Or (BindingFlags.Public Or (BindingFlags.Static Or BindingFlags.Instance)))
            If Me.AllowInternalMembers(targetType) Then
                bindingAttr = (bindingAttr Or BindingFlags.NonPublic)
            End If
            Dim infoArray As MemberInfo() = targetType.GetMember(name, (MemberTypes.Property Or MemberTypes.Field), bindingAttr)
            If (Not infoArray Is Nothing) Then
                Dim length As Integer = infoArray.Length
                If (length = 1) Then
                    Return infoArray(0)
                End If
                If (length > 1) Then
                    Dim i As Integer
                    For i = 0 To length - 1
                        Dim info As MemberInfo = infoArray(i)
                        Dim info2 As PropertyInfo = DirectCast(info, PropertyInfo)
                        Dim indexParameters As ParameterInfo() = info2.GetIndexParameters
                        If ((indexParameters Is Nothing) OrElse (indexParameters.Length = 0)) Then
                            Return info2
                        End If
                    Next i
                End If
            End If
            If targetType.IsInterface Then
                Return RuleValidation.ResolveProperty(targetType, name, bindingAttr)
            End If
            Return Nothing
        End Function

        Friend Function ResolveIndexerProperty(ByVal targetType As Type, ByVal bindingFlags As BindingFlags, ByVal argumentExprs As List([Of] CodeExpression), <Out> ByRef [error] As ValidationError) As RulePropertyExpressionInfo
            Dim str As String
            Dim count As Integer = argumentExprs.Count
            If (count < 1) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.IndexerCountMismatch, New Object() { count })
                [error] = New ValidationError(str, &H19F)
                Return Nothing
            End If
            Dim arguments As New List([Of] Argument)(count)
            Dim expression As CodeExpression
            For Each expression In argumentExprs
                arguments.Add(New Argument(expression, Me))
            Next
            Dim indexerProperties As List([Of] PropertyInfo) = RuleValidation.GetIndexerProperties(RuleValidation.GetCandidateTargetTypes(targetType), bindingFlags)
            If (indexerProperties.Count = 0) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.IndexerNotFound, New Object() { RuleDecompiler.DecompileType(targetType) })
                [error] = New ValidationError(str, &H1A0)
                Return Nothing
            End If
            Dim candidates As List([Of] CandidateMember) = RuleValidation.GetCandidateIndexers(indexerProperties, arguments, [error])
            If (candidates Is Nothing) Then
                Return Nothing
            End If
            Dim member As CandidateMember = Me.FindBestCandidate(targetType, candidates, arguments)
            If (member Is Nothing) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.AmbiguousIndexerMatch, New Object(0  - 1) {})
                [error] = New ValidationError(str, &H54A)
                Return Nothing
            End If
            Dim pi As PropertyInfo = DirectCast(member.Member, PropertyInfo)
            Return New RulePropertyExpressionInfo(pi, pi.PropertyType, member.IsExpanded)
        End Function

        Friend Function ResolveMethod(ByVal targetType As Type, ByVal methodName As String, ByVal methodBindingFlags As BindingFlags, ByVal argumentExprs As List([Of] CodeExpression), <Out> ByRef [error] As ValidationError) As RuleMethodInvokeExpressionInfo
            Dim str As String
            Dim arguments As New List([Of] Argument)(argumentExprs.Count)
            Dim expression As CodeExpression
            For Each expression In argumentExprs
                arguments.Add(New Argument(expression, Me))
            Next
            Dim candidateTargetTypes As List([Of] Type) = RuleValidation.GetCandidateTargetTypes(targetType)
            Dim methods As List([Of] MethodInfo) = Me.GetNamedMethods(candidateTargetTypes, methodName, methodBindingFlags)
            If (methods.Count = 0) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.UnknownMethod, New Object() { methodName, RuleDecompiler.DecompileType(targetType) })
                [error] = New ValidationError(str, &H137)
                Return Nothing
            End If
            Dim candidates As List([Of] CandidateMember) = RuleValidation.GetCandidateMethods(methodName, methods, arguments, [error])
            If (candidates Is Nothing) Then
                Return Nothing
            End If
            Dim member As CandidateMember = Me.FindBestCandidate(targetType, candidates, arguments)
            If (member Is Nothing) Then
                str = String.Format(CultureInfo.CurrentCulture, Messages.AmbiguousMatch, New Object() { methodName })
                [error] = New ValidationError(str, &H54A)
                Return Nothing
            End If
            Return New RuleMethodInvokeExpressionInfo(DirectCast(member.Member, MethodInfo), member.IsExpanded)
        End Function

        Friend Shared Function ResolveProperty(ByVal targetType As Type, ByVal propertyName As String, ByVal bindingFlags As BindingFlags) As PropertyInfo
            Dim info As PropertyInfo = RuleValidation.GetProperty(targetType, propertyName, bindingFlags)
            If ((info Is Nothing) AndAlso targetType.IsInterface) Then
                Dim interfaces As Type() = targetType.GetInterfaces
                Dim list As New List([Of] Type)
                list.AddRange(interfaces)
                Dim i As Integer
                For i = 0 To list.Count - 1
                    info = RuleValidation.GetProperty(list.Item(i), propertyName, bindingFlags)
                    If (Not info Is Nothing) Then
                        Return info
                    End If
                    Dim collection As Type() = list.Item(i).GetInterfaces
                    If (collection.Length > 0) Then
                        list.AddRange(collection)
                    End If
                Next i
            End If
            Return info
        End Function

        Friend Function ResolveType(ByVal typeRef As CodeTypeReference) As Type
            Dim type As Type = Nothing
            If Not Me.typeRefMap.TryGetValue(typeRef, type) Then
                type = Me.FindType(typeRef.BaseType)
                If (type Is Nothing) Then
                    Dim qualifiedName As String = [TryCast](typeRef.UserData.Item("QualifiedName"),String)
                    type = Me.ResolveType(qualifiedName)
                    If (Not type Is Nothing) Then
                        Me.typeRefMap.Add(typeRef, type)
                        Return type
                    End If
                    Dim item As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.UnknownType, New Object() { typeRef.BaseType }), &H549)
                    item.UserData.Item("ErrorObject") = typeRef
                    Me.Errors.Add(item)
                    Return Nothing
                End If
                If (typeRef.TypeArguments.Count > 0) Then
                    Dim typeArguments As Type() = New Type(typeRef.TypeArguments.Count  - 1) {}
                    Dim i As Integer
                    For i = 0 To typeRef.TypeArguments.Count - 1
                        Dim reference As CodeTypeReference = typeRef.TypeArguments.Item(i)
                        If reference.BaseType.StartsWith("[", StringComparison.Ordinal) Then
                            reference.BaseType = reference.BaseType.Substring(1, (reference.BaseType.Length - 2))
                        End If
                        typeArguments(i) = Me.ResolveType(reference)
                        If (typeArguments(i) Is Nothing) Then
                            Return Nothing
                        End If
                    Next i
                    type = type.MakeGenericType(typeArguments)
                    If (type Is Nothing) Then
                        Dim builder As New StringBuilder(typeRef.BaseType)
                        Dim str3 As String = "<"
                        Dim type2 As Type
                        For Each type2 In typeArguments
                            builder.Append(str3)
                            str3 = ","
                            builder.Append(RuleDecompiler.DecompileType(type2))
                        Next
                        builder.Append(">")
                        Dim error2 As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.UnknownGenericType, New Object() { builder.ToString }), &H549)
                        error2.UserData.Item("ErrorObject") = typeRef
                        Me.Errors.Add(error2)
                        Return Nothing
                    End If
                End If
                If (Not type Is Nothing) Then
                    Dim arrayElementType As CodeTypeReference = typeRef
                    If (arrayElementType.ArrayRank > 0) Then
                        Do
                            type = If((arrayElementType.ArrayRank = 1), type.MakeArrayType, type.MakeArrayType(arrayElementType.ArrayRank))
                            arrayElementType = arrayElementType.ArrayElementType
                        Loop While (arrayElementType.ArrayRank > 0)
                    End If
                End If
                If (Not type Is Nothing) Then
                    Me.typeRefMap.Add(typeRef, type)
                    typeRef.UserData.Item("QualifiedName") = type.AssemblyQualifiedName
                End If
            End If
            Return type
        End Function

        Friend Function ResolveType(ByVal qualifiedName As String) As Type
            Dim type As Type = Nothing
            If (Not qualifiedName Is Nothing) Then
                type = Me.typeProvider.GetType(qualifiedName, False)
                If (type Is Nothing) Then
                    type = Type.GetType(qualifiedName, False)
                End If
            End If
            Return type
        End Function

        Private Sub SetExtensionAttribute()
            Me.extensionAttribute = Me.typeProvider.GetType("System.Runtime.CompilerServices.ExtensionAttribute, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", False)
            If (Me.extensionAttribute Is Nothing) Then
                Me.extensionAttribute = RuleValidation.defaultExtensionAttribute
            End If
        End Sub

        <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
        Friend Shared Function StandardImplicitConversion(ByVal rhsType As Type, ByVal lhsType As Type, ByVal rhsExpression As CodeExpression, <Out> ByRef [error] As ValidationError) As Boolean
            [error] = Nothing
            If (rhsType Is lhsType) Then
                Return True
            End If
            If (rhsType Is GetType(NullLiteral)) Then
                If ConditionHelper.IsNonNullableValueType(lhsType) Then
                    Dim errorText As String = String.Format(CultureInfo.CurrentCulture, Messages.AssignNotAllowed, New Object() { Messages.NullValue, RuleDecompiler.DecompileType(lhsType) })
                    [error] = New ValidationError(errorText, &H545)
                    Return False
                End If
                Return True
            End If
            Dim flag As Boolean = ConditionHelper.IsNullableValueType(lhsType)
            If ConditionHelper.IsNullableValueType(rhsType) Then
                If Not flag Then
                    Return (lhsType Is GetType(Object))
                End If
                rhsType = Nullable.GetUnderlyingType(rhsType)
            End If
            If flag Then
                lhsType = Nullable.GetUnderlyingType(lhsType)
            End If
            If (lhsType Is rhsType) Then
                Return True
            End If
            If TypeProvider.IsAssignable(lhsType, rhsType) Then
                Return True
            End If
            If lhsType.IsEnum Then
                Dim expression As CodePrimitiveExpression = [TryCast](rhsExpression,CodePrimitiveExpression)
                If ((Not expression Is Nothing) AndAlso (Not expression.Value Is Nothing)) Then
                    Select Case Type.GetTypeCode(expression.Value.GetType)
                        Case TypeCode.Char
                            Return (DirectCast(expression.Value, Char) = ChrW(0))
                        Case TypeCode.[SByte]
                            Return ([CSByte](expression.Value) = 0)
                        Case TypeCode.Byte
                            Return (CByte(expression.Value) = 0)
                        Case TypeCode.Int16
                            Return (CShort(expression.Value) = 0)
                        Case TypeCode.UInt16
                            Return ([CUShort](expression.Value) = 0)
                        Case TypeCode.Int32
                            Return (CInt(expression.Value) = 0)
                        Case TypeCode.UInt32
                            Return (DirectCast(expression.Value, UInt32) = 0)
                        Case TypeCode.Int64
                            Return (CLng(expression.Value) = 0)
                        Case TypeCode.UInt64
                            Return ([CULng](expression.Value) = 0)
                    End Select
                End If
                Return False
            End If
            If Not rhsType.IsEnum Then
                Dim typeCode As TypeCode = Type.GetTypeCode(lhsType)
                Dim code2 As TypeCode = Type.GetTypeCode(rhsType)
                Select Case typeCode
                    Case TypeCode.Char
                        Select Case code2
                            Case TypeCode.Char
                                Return True
                            Case TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                        End Select
                        Return False
                    Case TypeCode.[SByte]
                        Select Case code2
                            Case TypeCode.Char, TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                            Case TypeCode.[SByte]
                                Return True
                        End Select
                        Return False
                    Case TypeCode.Byte
                        Select Case code2
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                            Case TypeCode.Byte
                                Return True
                        End Select
                        Return False
                    Case TypeCode.Int16
                        Select Case code2
                            Case TypeCode.Char, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                            Case TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16
                                Return True
                        End Select
                        Return False
                    Case TypeCode.UInt16
                        Select Case code2
                            Case TypeCode.Char, TypeCode.Byte, TypeCode.UInt16
                                Return True
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                        End Select
                        Return False
                    Case TypeCode.Int32
                        Select Case code2
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32
                                Return True
                            Case TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                        End Select
                        Return False
                    Case TypeCode.UInt32
                        Select Case code2
                            Case TypeCode.Char, TypeCode.Byte, TypeCode.UInt16, TypeCode.UInt32
                                Return True
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                        End Select
                        Return False
                    Case TypeCode.Int64
                        Select Case code2
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64
                                Return True
                            Case TypeCode.UInt64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                        End Select
                        Return False
                    Case TypeCode.UInt64
                        Select Case code2
                            Case TypeCode.Char, TypeCode.Byte, TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64
                                Return True
                            Case TypeCode.[SByte], TypeCode.Int16, TypeCode.Int32, TypeCode.Int64
                                Return RuleValidation.CheckValueRange(rhsExpression, lhsType, [error])
                        End Select
                        Return False
                    Case TypeCode.Single
                        Select Case code2
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single
                                Return True
                        End Select
                        Return False
                    Case TypeCode.Double
                        Select Case code2
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Single, TypeCode.Double
                                Return True
                        End Select
                        Return False
                    Case TypeCode.Decimal
                        Select Case code2
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64, TypeCode.Decimal
                                Return True
                            Case TypeCode.Single, TypeCode.Double
                                goto Label_022D
                        End Select
                        goto Label_022D
                End Select
            End If
            Return False
        Label_022D:
            Return False
        End Function

        Friend Shared Function TypesAreAssignable(ByVal rhsType As Type, ByVal lhsType As Type, ByVal rhsExpression As CodeExpression, <Out> ByRef [error] As ValidationError) As Boolean
            If Not RuleValidation.StandardImplicitConversion(rhsType, lhsType, rhsExpression, [error]) Then
                If (Not [error] Is Nothing) Then
                    Return False
                End If
                If (RuleValidation.FindImplicitConversion(rhsType, lhsType, [error]) Is Nothing) Then
                    Return False
                End If
            End If
            Return True
        End Function

        Friend Function ValidateConditionExpression(ByVal expression As CodeExpression) As Boolean
            If (expression Is Nothing) Then
                Throw New ArgumentNullException("expression")
            End If
            Dim info As RuleExpressionInfo = RuleExpressionWalker.Validate(Me, expression, False)
            If (info Is Nothing) Then
                Return False
            End If
            Dim expressionType As Type = info.ExpressionType
            If (Not RuleValidation.IsValidBooleanResult(expressionType) AndAlso ((Not expressionType Is Nothing) OrElse (Me.Errors.Count = 0))) Then
                Dim item As New ValidationError(Messages.ConditionMustBeBoolean, &H547)
                item.UserData.Item("ErrorObject") = expression
                Me.Errors.Add(item)
            End If
            Return (Me.Errors.Count = 0)
        End Function

        Friend Function ValidateMemberAccess(ByVal targetExpression As CodeExpression, ByVal targetType As Type, ByVal accessorMethod As FieldInfo, ByVal memberName As String, ByVal parentExpr As CodeExpression) As Boolean
            Return Me.ValidateMemberAccess(targetExpression, targetType, memberName, parentExpr, accessorMethod.DeclaringType.Assembly, RuleValidation.IsPrivate(accessorMethod), RuleValidation.IsInternal(accessorMethod), accessorMethod.IsStatic)
        End Function

        Friend Function ValidateMemberAccess(ByVal targetExpression As CodeExpression, ByVal targetType As Type, ByVal accessorMethod As MethodInfo, ByVal memberName As String, ByVal parentExpr As CodeExpression) As Boolean
            Return Me.ValidateMemberAccess(targetExpression, targetType, memberName, parentExpr, accessorMethod.DeclaringType.Assembly, RuleValidation.IsPrivate(accessorMethod), RuleValidation.IsInternal(accessorMethod), accessorMethod.IsStatic)
        End Function

        Private Function ValidateMemberAccess(ByVal targetExpression As CodeExpression, ByVal targetType As Type, ByVal memberName As String, ByVal parentExpr As CodeExpression, ByVal methodAssembly As Assembly, ByVal isPrivate As Boolean, ByVal isInternal As Boolean, ByVal isStatic As Boolean) As Boolean
            If (isStatic <> TypeOf targetExpression Is CodeTypeReferenceExpression) Then
                Dim str As String
                Dim num As Integer
                If isStatic Then
                    str = String.Format(CultureInfo.CurrentCulture, Messages.StaticMember, New Object() { memberName })
                    num = &H561
                Else
                    str = String.Format(CultureInfo.CurrentCulture, Messages.NonStaticMember, New Object() { memberName })
                    num = &H562
                End If
                Dim item As New ValidationError(str, num)
                item.UserData.Item("ErrorObject") = parentExpr
                Me.Errors.Add(item)
                Return False
            End If
            If (isPrivate AndAlso (Not targetType Is Me.ThisType)) Then
                Dim error2 As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.CannotAccessPrivateMember, New Object() { memberName, RuleDecompiler.DecompileType(targetType) }), &H54A)
                error2.UserData.Item("ErrorObject") = parentExpr
                Me.Errors.Add(error2)
                Return False
            End If
            If (isInternal AndAlso (Not Me.ThisType.Assembly Is methodAssembly)) Then
                Dim error3 As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.CannotAccessInternalMember, New Object() { memberName, RuleDecompiler.DecompileType(targetType) }), &H54A)
                error3.UserData.Item("ErrorObject") = parentExpr
                Me.Errors.Add(error3)
                Return False
            End If
            Return True
        End Function

        Friend Function ValidateSubexpression(ByVal expr As CodeExpression, ByVal ruleExpr As RuleExpressionInternal, ByVal isWritten As Boolean) As RuleExpressionInfo
            Dim info As RuleExpressionInfo = ruleExpr.Validate(expr, Me, isWritten)
            If (Not info Is Nothing) Then
                Me.expressionInfoMap.Item(expr) = info
            End If
            Return info
        End Function


        ' Properties
        Public ReadOnly Property Errors As ValidationErrorCollection
            Get
                Return Me.errors
            End Get
        End Property

        Friend ReadOnly Property ExtensionMethods As List([Of] ExtensionMethodInfo)
            Get
                If (Me.extensionMethods Is Nothing) Then
                    Me.DetermineExtensionMethods
                End If
                Return Me.extensionMethods
            End Get
        End Property

        Public ReadOnly Property ThisType As Type
            Get
                Return Me.thisType
            End Get
        End Property


        ' Fields
        Private activeParentNodes As Stack([Of] CodeExpression)
        Private authorizedTypes As List([Of] AuthorizedType)
        Private checkStaticType As Boolean
        Private Shared defaultExtensionAttribute As Type = RuleValidation.GetDefaultExtensionAttribute
        Private errors As ValidationErrorCollection
        Private expressionInfoMap As Dictionary([Of] CodeExpression, RuleExpressionInfo)
        Private extensionAttribute As Type
        Private Const ExtensionAttributeFullName As String = "System.Runtime.CompilerServices.ExtensionAttribute, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        Private extensionMethods As List([Of] ExtensionMethodInfo)
        Private seenAssemblies As List([Of] Assembly)
        Private thisType As Type
        Private typeProvider As ITypeProvider
        Private typeRefMap As Dictionary([Of] CodeTypeReference, Type)
        Private typesUsed As Dictionary([Of] String, Type)

        ' Nested Types
        Private Class Argument
            ' Methods
            Friend Sub New(ByVal type As Type)
                Me.direction = FieldDirection.In
                Me.type = type
            End Sub

            Friend Sub New(ByVal expr As CodeExpression, ByVal validation As RuleValidation)
                Me.expression = expr
                Me.direction = FieldDirection.In
                Dim expression As CodeDirectionExpression = [TryCast](expr,CodeDirectionExpression)
                If (Not expression Is Nothing) Then
                    Me.direction = expression.Direction
                End If
                Me.type = validation.ExpressionInfo(expr).ExpressionType
            End Sub


            ' Fields
            Friend direction As FieldDirection
            Friend expression As CodeExpression
            Friend type As Type
        End Class

        Private Delegate Function BuildArgCountMismatchError(ByVal name As String, ByVal numArguments As Integer) As ValidationError

        Private Class CandidateMember
            ' Methods
            Friend Sub New(ByVal member As MemberInfo)
                Me.New(member, CandidateMember.noParameters, CandidateMember.noSignature, Form.Normal)
            End Sub

            Friend Sub New(ByVal member As MemberInfo, ByVal parameters As ParameterInfo(), ByVal signature As List([Of] CandidateParameter), ByVal form As Form)
                Me.Member = member
                Me.memberParameters = parameters
                Me.signature = signature
                Me.form = form
            End Sub

            <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
            Friend Function CompareMember(ByVal targetType As Type, ByVal other As CandidateMember, ByVal arguments As List([Of] Argument), ByVal validator As RuleValidation) As Integer
                Dim num As Integer = 1
                Dim num2 As Integer = -1
                Dim num3 As Integer = 0
                Dim declaringType As Type = Me.Member.DeclaringType
                Dim toType As Type = other.Member.DeclaringType
                If (Not declaringType Is toType) Then
                    If TypeProvider.IsAssignable(toType, declaringType) Then
                        Return num
                    End If
                    If TypeProvider.IsAssignable(declaringType, toType) Then
                        Return num2
                    End If
                End If
                Dim flag As Boolean = False
                Dim flag2 As Boolean = False
                Dim flag3 As Boolean = True
                Dim member As ExtensionMethodInfo = [TryCast](Me.Member,ExtensionMethodInfo)
                Dim info2 As ExtensionMethodInfo = [TryCast](other.Member,ExtensionMethodInfo)
                If ((member Is Nothing) AndAlso (Not info2 Is Nothing)) Then
                    Return num
                End If
                If ((Not member Is Nothing) AndAlso (info2 Is Nothing)) Then
                    Return num2
                End If
                If ((Not member Is Nothing) AndAlso (Not info2 Is Nothing)) Then
                    Dim test As String() = member.DeclaringType.FullName.Split(New Char() { "."c })
                    Dim strArray2 As String() = info2.DeclaringType.FullName.Split(New Char() { "."c })
                    Dim reference As String() = validator.thisType.FullName.Split(New Char() { "."c })
                    Dim num4 As Integer = CandidateMember.MatchNameSpace(test, reference)
                    Dim num5 As Integer = CandidateMember.MatchNameSpace(strArray2, reference)
                    If (num4 > num5) Then
                        Return num
                    End If
                    If (num4 < num5) Then
                        Return num2
                    End If
                    Dim parameter As New CandidateParameter(member.AssumedDeclaringType)
                    Dim parameter2 As New CandidateParameter(info2.AssumedDeclaringType)
                    If Not parameter.Equals(parameter2) Then
                        flag3 = False
                        Dim num6 As Integer = parameter.CompareConversion(parameter2, New Argument(targetType))
                        If (num6 < 0) Then
                            flag2 = True
                        ElseIf (num6 > 0) Then
                            flag = True
                        End If
                    End If
                    Dim i As Integer
                    For i = 0 To arguments.Count - 1
                        Dim parameter3 As CandidateParameter = Me.signature.Item(i)
                        Dim parameter4 As CandidateParameter = other.signature.Item(i)
                        If Not parameter3.Equals(parameter4) Then
                            flag3 = False
                        End If
                        Dim num8 As Integer = parameter3.CompareConversion(parameter4, arguments.Item(i))
                        If (num8 < 0) Then
                            flag2 = True
                        ElseIf (num8 > 0) Then
                            flag = True
                        End If
                    Next i
                    If (flag AndAlso Not flag2) Then
                        Return num
                    End If
                    If (Not flag AndAlso flag2) Then
                        Return num2
                    End If
                Else
                    Dim j As Integer
                    For j = 0 To arguments.Count - 1
                        Dim parameter5 As CandidateParameter = Me.signature.Item(j)
                        Dim parameter6 As CandidateParameter = other.signature.Item(j)
                        If Not parameter5.Equals(parameter6) Then
                            flag3 = False
                        End If
                        Dim num10 As Integer = parameter5.CompareConversion(parameter6, arguments.Item(j))
                        If (num10 < 0) Then
                            Return num2
                        End If
                        If (num10 > 0) Then
                            flag = True
                        End If
                    Next j
                    If flag Then
                        Return num
                    End If
                End If
                If flag3 Then
                    If ((Me.form = Form.Normal) AndAlso (other.form = Form.Expanded)) Then
                        Return num
                    End If
                    If ((Me.form = Form.Expanded) AndAlso (other.form = Form.Normal)) Then
                        Return num2
                    End If
                    If ((Me.form <> Form.Expanded) OrElse (other.form <> Form.Expanded)) Then
                        Return num3
                    End If
                    Dim length As Integer = Me.memberParameters.Length
                    Dim num12 As Integer = other.memberParameters.Length
                    If (length > num12) Then
                        Return num
                    End If
                    If (num12 > length) Then
                        Return num2
                    End If
                End If
                Return num3
            End Function

            Private Shared Function MatchNameSpace(ByVal test As String(), ByVal reference As String()) As Integer
                Dim num2 As Integer = Math.Min(test.Length, reference.Length)
                Dim index As Integer = 0
                Do While (index < num2)
                    If (test(index) <> reference(index)) Then
                        Return index
                    End If
                    index += 1
                Loop
                Return index
            End Function


            ' Properties
            Friend ReadOnly Property IsExpanded As Boolean
                Get
                    Return (Me.form = Form.Expanded)
                End Get
            End Property


            ' Fields
            Private form As Form
            Friend Member As MemberInfo
            Private memberParameters As ParameterInfo()
            Private Shared noParameters As ParameterInfo() = New ParameterInfo(0  - 1) {}
            Private Shared noSignature As List([Of] CandidateParameter) = New List([Of] CandidateParameter)
            Private signature As List([Of] CandidateParameter)

            ' Nested Types
            Friend Enum Form
                ' Fields
                Expanded = 1
                Normal = 0
            End Enum
        End Class

        Private Class CandidateParameter
            ' Methods
            Friend Sub New(ByVal paramInfo As ParameterInfo)
                Me.direction = FieldDirection.In
                If paramInfo.IsOut Then
                    Me.direction = FieldDirection.Out
                ElseIf paramInfo.ParameterType.IsByRef Then
                    Me.direction = FieldDirection.Ref
                End If
                Me.type = paramInfo.ParameterType
            End Sub

            Friend Sub New(ByVal type As Type)
                Me.type = type
                Me.direction = FieldDirection.In
            End Sub

            <SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")> _
            Private Shared Function BetterSignedConversion(ByVal t1 As Type, ByVal t2 As Type) As Boolean
                Dim typeCode As TypeCode = Type.GetTypeCode(t1)
                Dim code2 As TypeCode = Type.GetTypeCode(t2)
                Select Case typeCode
                    Case TypeCode.[SByte]
                        Select Case code2
                            Case TypeCode.Byte, TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64
                                Return True
                        End Select
                        Exit Select
                    Case TypeCode.Int16
                        Select Case code2
                            Case TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64
                                Return True
                        End Select
                        Exit Select
                    Case TypeCode.Int32
                        If ((code2 <> TypeCode.UInt32) AndAlso (code2 <> TypeCode.UInt64)) Then
                            Exit Select
                        End If
                        Return True
                    Case TypeCode.Int64
                        If (code2 <> TypeCode.UInt64) Then
                            Exit Select
                        End If
                        Return True
                    Case TypeCode.Object
                        If Not ConditionHelper.IsNullableValueType(t1) Then
                            Return False
                        End If
                        t1 = t1.GetGenericArguments(0)
                        If ConditionHelper.IsNullableValueType(t2) Then
                            t2 = t2.GetGenericArguments(0)
                        End If
                        Return CandidateParameter.BetterSignedConversion(t1, t2)
                End Select
                Return False
            End Function

            Friend Function CompareConversion(ByVal otherParam As CandidateParameter, ByVal argument As Argument) As Integer
                Dim num As Integer = 1
                Dim num2 As Integer = -1
                If (Not Me.type Is otherParam.type) Then
                    Dim error As ValidationError
                    If (argument.type Is Me.type) Then
                        Return num
                    End If
                    If (argument.type Is otherParam.type) Then
                        Return num2
                    End If
                    Dim flag As Boolean = RuleValidation.TypesAreAssignable(Me.type, otherParam.type, Nothing, [error])
                    Dim flag2 As Boolean = RuleValidation.TypesAreAssignable(otherParam.type, Me.type, Nothing, [error])
                    If (flag AndAlso Not flag2) Then
                        Return num
                    End If
                    If (flag2 AndAlso Not flag) Then
                        Return num2
                    End If
                    If CandidateParameter.BetterSignedConversion(Me.type, otherParam.type) Then
                        Return num
                    End If
                    If CandidateParameter.BetterSignedConversion(otherParam.type, Me.type) Then
                        Return num2
                    End If
                End If
                Return 0
            End Function

            Public Overrides Function Equals(ByVal obj As Object) As Boolean
                Dim parameter As CandidateParameter = [TryCast](obj,CandidateParameter)
                If (parameter Is Nothing) Then
                    Return False
                End If
                Return ((Me.direction = parameter.direction) AndAlso (Me.type Is parameter.type))
            End Function

            Public Overrides Function GetHashCode() As Integer
                Return (Me.direction.GetHashCode Xor Me.type.GetHashCode)
            End Function

            Friend Function Match(ByVal argument As Argument, ByVal methodName As String, ByVal argPosition As Integer, <Out> ByRef [error] As ValidationError) As Boolean
                Dim str As String
                If (Me.direction = argument.direction) Then
                    If (Me.type.IsByRef AndAlso (Not Me.type Is argument.type)) Then
                        str = String.Format(CultureInfo.CurrentCulture, Messages.MethodArgumentTypeMismatch, New Object() { argPosition, methodName, RuleDecompiler.DecompileType(argument.type), RuleDecompiler.DecompileType(Me.type) })
                        [error] = New ValidationError(str, &H198)
                        Return False
                    End If
                    If RuleValidation.TypesAreAssignable(argument.type, Me.type, argument.expression, [error]) Then
                        Return True
                    End If
                    If ([error] Is Nothing) Then
                        str = String.Format(CultureInfo.CurrentCulture, Messages.MethodArgumentTypeMismatch, New Object() { argPosition, methodName, RuleDecompiler.DecompileType(argument.type), RuleDecompiler.DecompileType(Me.type) })
                        [error] = New ValidationError(str, &H198)
                    End If
                    Return False
                End If
                Dim str2 As String = ""
                Select Case Me.direction
                    Case FieldDirection.In
                        str2 = "in"
                        Exit Select
                    Case FieldDirection.Out
                        str2 = "out"
                        Exit Select
                    Case FieldDirection.Ref
                        str2 = "ref"
                        Exit Select
                End Select
                str = String.Format(CultureInfo.CurrentCulture, Messages.MethodDirectionMismatch, New Object() { argPosition, methodName, str2 })
                [error] = New ValidationError(str, &H197)
                Return False
            End Function


            ' Fields
            Private direction As FieldDirection
            Private type As Type
        End Class
    End Class
End Namespace

